Passed
Push — master ( 023d75...2211cf )
by EMP
04:46
created

main.js ➔ reloadAccount   C

Complexity

Conditions 11

Size

Total Lines 70
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 46
dl 0
loc 70
rs 5.4
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like main.js ➔ reloadAccount often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
"use strict";
2
3
sodium.ready.then(function() {
1 ignored issue
show
Bug introduced by
The variable sodium seems to be never declared. If this is a global, consider adding a /** global: sodium */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
4
5
const ae = new AllEars(function(ok) {
1 ignored issue
show
Bug introduced by
The variable AllEars seems to be never declared. If this is a global, consider adding a /** global: AllEars */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
6
	if (ok) {
7
		const greeting = localStorage.greeting;
1 ignored issue
show
Bug introduced by
The variable localStorage seems to be never declared. If this is a global, consider adding a /** global: localStorage */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
8
		if (greeting) {
9
			document.getElementById("greeting").textContent = greeting;
10
			document.getElementById("txt_pg").value = greeting;
11
		}
12
13
		document.getElementById("txt_skey").style.background = "#466";
14
		document.getElementById("txt_skey").maxLength = "64";
15
	} else {
16
		console.log("Failed to load All-Ears");
17
	}
18
});
19
20
function TabState(cur, max, btnDele, btnUpdt) {
21
	this.cur = cur;
22
	this.max = max;
23
	this.btnDele = btnDele;
24
	this.btnUpdt = btnUpdt;
25
}
26
27
const tabs = [
28
	new TabState(0, 0, false, true), // Inbox
29
	new TabState(0, 0, false, true), // Outbx
30
	new TabState(0, 2, true, false), // Write
31
	new TabState(0, 2, false, false), // Notes
32
	new TabState(0, 3, false, true) // Tools
33
];
34
35
let showHeaders = false;
36
37
let tab = 0;
38
const TAB_INBOX = 0;
39
const TAB_DRBOX = 1;
40
const TAB_WRITE = 2;
41
const TAB_NOTES = 3;
42
const TAB_TOOLS = 4;
43
44
// Helper functions
45
function getCountryName(countryCode) {
46
	const opts = document.getElementById("gatekeeper_country");
47
48
	for (let i = 0; i < opts.length; i++) {
49
		if (opts[i].value === countryCode) {
50
			return opts[i].textContent;
51
		}
52
	}
53
54
	return "Unknown countrycode: " + countryCode;
55
}
56
57
function getCountryFlag(countryCode) {
58
	return sodium.to_string(new Uint8Array([
1 ignored issue
show
Bug introduced by
The variable sodium seems to be never declared. If this is a global, consider adding a /** global: sodium */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
59
		240, 159, 135, 166 + countryCode.codePointAt(0) - 65,
60
		240, 159, 135, 166 + countryCode.codePointAt(1) - 65
61
	]));
62
}
63
64
function getMsgId(num) {
65
	let i;
66
	if (ae.GetExtMsgHeaders(num).toLowerCase().slice(0, 11) === "message-id:") {
67
		i = 0;
68
	} else {
69
		i = ae.GetExtMsgHeaders(num).toLowerCase().indexOf("\nmessage-id:");
70
		if (i < 1) return "ERR";
71
		i++;
72
	}
73
74
	const x = ae.GetExtMsgHeaders(num).slice(i + 11).trim();
75
	if (x[0] !== "<") return "ERR2";
76
	return x.slice(1, x.indexOf(">"));
77
}
78
79
function clearDisplay() {
80
	let el = document.getElementById("midright").getElementsByTagName("img");
81
	if (el.length !== 1) el = document.getElementById("midright").getElementsByTagName("audio");
82
	if (el.length !== 1) el = document.getElementById("midright").getElementsByTagName("video");
83
	if (el.length !== 1) el = document.getElementById("midright").getElementsByTagName("embed");
84
	if (el.length !== 1) el = document.getElementById("midright").getElementsByTagName("iframe");
85
	if (el.length !== 1) return;
86
87
	URL.revokeObjectURL(el[0].src);
1 ignored issue
show
Bug introduced by
The variable URL seems to be never declared. If this is a global, consider adding a /** global: URL */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
88
	el[0].remove();
89
}
90
91
function displayFile(num) {
92
	clearDisplay();
93
94
	document.getElementById("midright").scroll(0, 0);
95
	document.getElementById("btn_reply").disabled = true;
96
	document.getElementById("btn_mdele").disabled = true;
97
98
	document.getElementById("midright").children[0].hidden = true;
99
	document.getElementById("midright").children[1].textContent = ae.GetUplMsgTitle(num);
100
101
	switch (ae.GetUplMsgType(num)) {
102
		case "text": {
103
			document.getElementById("midright").children[2].hidden = false;
104
			document.getElementById("midright").children[2].textContent = sodium.to_string(ae.GetUplMsgBody(num));
1 ignored issue
show
Bug introduced by
The variable sodium seems to be never declared. If this is a global, consider adding a /** global: sodium */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
105
		break;}
106
107
		case "image": {
108
			document.getElementById("midright").children[2].hidden = true;
109
			const img = document.createElement("img");
110
			img.src = URL.createObjectURL(new Blob([ae.GetUplMsgBody(num).buffer]));
2 ignored issues
show
Bug introduced by
The variable Blob seems to be never declared. If this is a global, consider adding a /** global: Blob */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
Bug introduced by
The variable URL seems to be never declared. If this is a global, consider adding a /** global: URL */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
111
			document.getElementById("midright").appendChild(img);
112
113
			img.onclick = function() {
114
				if (!document.fullscreen)
115
					img.requestFullscreen();
116
				else
117
					document.exitFullscreen();
118
			};
119
		break;}
120
121
		case "audio": {
122
			document.getElementById("midright").children[2].hidden = true;
123
			const el = document.createElement("audio");
124
			el.controls = "controls";
125
			el.src = URL.createObjectURL(new Blob([ae.GetUplMsgBody(num).buffer]));
126
			document.getElementById("midright").appendChild(el);
127
		break;}
128
129
		case "video": {
130
			document.getElementById("midright").children[2].hidden = true;
131
			const el = document.createElement("video");
132
			el.controls = "controls";
133
			el.src = URL.createObjectURL(new Blob([ae.GetUplMsgBody(num).buffer]));
134
			document.getElementById("midright").appendChild(el);
135
		break;}
136
137
		case "pdf": {
138
			document.getElementById("midright").children[2].hidden = true;
139
			const el = document.createElement("embed");
140
			el.type = "application/pdf";
141
			el.src = URL.createObjectURL(new Blob([ae.GetUplMsgBody(num).buffer], {type: "application/pdf"}));
142
			document.getElementById("midright").appendChild(el);
143
		break;}
144
145
		case "html": {
146
			document.getElementById("midright").children[2].hidden = true;
147
			const el = document.createElement("iframe");
148
			el.allow = "";
149
			el.sandbox = "";
150
			el.csp = "base-uri 'none'; child-src 'none'; connect-src 'none'; default-src 'none'; font-src 'none'; form-action 'none'; frame-ancestors 'none'; frame-src 'none'; img-src 'none'; manifest-src 'none'; media-src 'none'; object-src 'none'; script-src 'none'; style-src 'none'; worker-src 'none';";
151
			el.srcdoc = sodium.to_string(ae.GetUplMsgBody(num).buffer);
152
			document.getElementById("midright").appendChild(el);
153
		break;}
154
	}
155
}
156
157
function displayMsg(isInt, num) {
158
	clearDisplay();
159
160
	document.getElementById("midright").scroll(0, 0);
161
162
	const ts = isInt? ae.GetIntMsgTime(num) : ae.GetExtMsgTime(num);
163
164
	document.getElementById("btn_reply").disabled = false;
165
	document.getElementById("btn_reply").onclick = function() {
166
		document.getElementById("write_recv").value = isInt? ae.GetIntMsgFrom(num) : ae.GetExtMsgFrom(num);
167
		document.getElementById("write_subj").value = "Re: " + (isInt ? ae.GetIntMsgTitle(num) : ae.GetExtMsgTitle(num));
168
		document.getElementById("write_rply").textContent = (isInt? "" : getMsgId(num));
169
		document.getElementById("btn_write").click();
170
		document.getElementById("div_write_1").hidden = false;
171
		document.getElementById("div_write_2").hidden = true;
172
		document.getElementById("write_body").focus();
173
		for (const opt of document.getElementById("write_from").options) {
174
			if (opt.value === (isInt ? ae.GetIntMsgTo(num) : ae.GetExtMsgTo(num))) {
175
				opt.selected = true;
176
			}
177
		}
178
	};
179
180
	document.getElementById("btn_mdele").disabled = false;
181
	document.getElementById("btn_mdele").onclick = function() {
182
		this.blur();
183
184
		ae.Message_Delete(isInt? ae.GetIntMsgIdHex(num) : ae.GetExtMsgIdHex(num), function(success) {
185
			if (!success) console.log("Failed delete");
186
		});
187
	};
188
189
	document.getElementById("midright").children[0].hidden = false;
190
	document.getElementById("midright").children[2].hidden = false;
191
192
	if (isInt) {
193
		document.getElementById("midright").children[1].textContent = ae.GetIntMsgTitle(num);
194
		document.getElementById("midright").children[2].textContent = ae.GetIntMsgBody(num);
195
	} else {
196
		document.getElementById("midright").children[2].innerHTML = "";
197
198
		const headers = document.createElement("p");
199
		headers.textContent = ae.GetExtMsgHeaders(num);
200
		headers.className = "mono";
201
		headers.hidden = !showHeaders;
202
		document.getElementById("midright").children[2].appendChild(headers);
203
204
		const body = document.createElement("p");
205
		body.textContent = ae.GetExtMsgBody(num);
206
		document.getElementById("midright").children[2].appendChild(body);
207
208
		document.getElementById("midright").children[1].textContent = ae.GetExtMsgTitle(num);
209
		document.getElementById("midright").children[1].onclick = function() {showHeaders = !showHeaders; headers.hidden = !showHeaders;};
210
		document.getElementById("midright").children[1].style.cursor = "pointer";
211
	}
212
213
	document.getElementById("readmsg_to").textContent = isInt ? ae.GetIntMsgTo(num) : ae.GetExtMsgTo(num);
214
215
	const tzOs = new Date().getTimezoneOffset();
216
	const tz = ((tzOs < 0) ? "+" : "-") + Math.floor(tzOs / -60).toString().padStart(2, "0") + (tzOs % 60 * -1).toString().padStart(2, "0");
217
	document.getElementById("readmsg_date").children[0].textContent = new Date((ts * 1000) + (tzOs * -60000)).toISOString().slice(0, 19).replace("T", " ") + " " + tz;
218
219
	if (!isInt) {
220
		document.getElementById("readmsg_ip").hidden = false;
221
		document.getElementById("readmsg_country").hidden = false;
222
		document.getElementById("readmsg_tls").hidden = false;
223
		document.getElementById("readmsg_greet").hidden = false;
224
		document.getElementById("readmsg_timing").hidden = false;
225
		document.getElementById("readmsg_envfrom").hidden = false;
226
227
		const cc = ae.GetExtMsgCountry(num);
228
229
		document.getElementById("readmsg_ip").children[0].textContent = ae.GetExtMsgIp(num);
230
		document.getElementById("readmsg_country").textContent = getCountryFlag(cc) + " " + getCountryName(cc);
231
		document.getElementById("readmsg_tls").children[0].textContent = ae.GetExtMsgTLS(num);
232
		document.getElementById("readmsg_greet").children[0].textContent = ae.GetExtMsgGreet(num);
233
		document.getElementById("readmsg_envfrom").textContent = ae.GetExtMsgFrom(num);
234
235
		let flagText = "";
236
		if (!ae.GetExtMsgFlagVPad(num)) flagText += "<abbr title=\"Invalid padding\">PAD</abbr> ";
237
		if (!ae.GetExtMsgFlagVSig(num)) flagText += "<abbr title=\"Invalid signature\">SIG</abbr> ";
238
		if (!ae.GetExtMsgFlagPExt(num)) flagText += "<abbr title=\"The sender did not use the Extended (ESMTP) protocol\">SMTP</abbr> ";
239
		if (!ae.GetExtMsgFlagQuit(num)) flagText += "<abbr title=\"The sender did not issue the required QUIT command\">QUIT</abbr> ";
240
		if (ae.GetExtMsgFlagRare(num)) flagText += "<abbr title=\"The sender issued unusual command(s)\">RARE</abbr> ";
241
		if (ae.GetExtMsgFlagFail(num)) flagText += "<abbr title=\"The sender issued invalid command(s)\">FAIL</abbr> ";
242
		if (ae.GetExtMsgFlagPErr(num)) flagText += "<abbr title=\"The sender violated the protocol\">PROT</abbr> ";
243
		document.getElementById("readmsg_flags").children[0].innerHTML = flagText.trim();
244
	} else {
245
		document.getElementById("readmsg_ip").hidden = true;
246
		document.getElementById("readmsg_country").hidden = true;
247
		document.getElementById("readmsg_tls").hidden = true;
248
		document.getElementById("readmsg_greet").hidden = true;
249
		document.getElementById("readmsg_timing").hidden = true;
250
		document.getElementById("readmsg_envfrom").hidden = true;
251
252
		let symbol = "<span title=\"Invalid level\">&#x26a0;</span>";
253
		if (ae.GetIntMsgFrom(num) === "system") {if (ae.GetIntMsgLevel(num) === 3) symbol = "<span title=\"System\">&#x1f162;</span>";} // S (System)
254
		else if (ae.GetIntMsgLevel(num) === 0) symbol = "<span title=\"Level 0 User\">&#x1f10c;</span>"; // 0
255
		else if (ae.GetIntMsgLevel(num) === 1) symbol = "<span title=\"Level 1 User\">&#x278a;</span>"; // 1
256
		else if (ae.GetIntMsgLevel(num) === 2) symbol = "<span title=\"Level 2 User\">&#x278b;</span>"; // 2
257
		else if (ae.GetIntMsgLevel(num) === 3) symbol = "<span title=\"Administrator\">&#x1f150;</span>"; // A (Admin)
258
		document.getElementById("readmsg_from").innerHTML = symbol + " " + ae.GetIntMsgFrom(num);
259
260
		let flagText = "";
261
		if (!ae.GetIntMsgFlagVPad(num)) flagText += "<abbr title=\"Invalid padding\">PAD</abbr> ";
262
		if (!ae.GetIntMsgFlagVSig(num)) flagText += "<abbr title=\"Invalid signature\">SIG</abbr> ";
263
		document.getElementById("readmsg_flags").children[0].innerHTML = flagText.trim();
264
	}
265
}
266
267
// Interface
268
function addMsg(isInt, i) {
269
	const row = document.getElementById("tbl_inbox").insertRow(-1);
270
	const cellTime = row.insertCell(-1);
271
	const cellSubj = row.insertCell(-1);
272
	const cellSnd1 = row.insertCell(-1);
273
	const cellSnd2 = row.insertCell(-1);
274
275
	const ts = isInt? ae.GetIntMsgTime(i) : ae.GetExtMsgTime(i);
276
	cellTime.setAttribute("data-ts", ts);
277
	cellTime.textContent = new Date((ts * 1000) + (new Date().getTimezoneOffset() * -60000)).toISOString().slice(0, 10);
278
279
	cellSubj.textContent = isInt? ae.GetIntMsgTitle(i) : ae.GetExtMsgTitle(i);
280
281
	if (isInt) {
282
		cellSnd1.textContent = ae.GetIntMsgFrom(i);
283
		cellSnd1.className = (ae.GetIntMsgFrom(i).length === 16) ? "mono" : "";
284
	} else {
285
		const from1 = ae.GetExtMsgFrom(i);
286
		const from2 = from1.substring(from1.indexOf("@") + 1);
287
		const cc = ae.GetExtMsgCountry(i);
288
289
		cellSnd1.textContent = from1.substring(0, from1.indexOf("@"));
290
291
		const flag = document.createElement("abbr");
292
		flag.textContent = getCountryFlag(cc);
293
		flag.title = getCountryName(cc);
294
		cellSnd2.appendChild(flag);
295
296
		const fromText = document.createElement("span");
297
		fromText.textContent = " " + from2;
298
		cellSnd2.appendChild(fromText);
299
	}
300
301
	row.onclick = function() {
302
		displayMsg(isInt, i);
303
	};
304
}
305
306
function getRowsPerPage() {
307
	const tbl = document.getElementById("tbl_inbox");
308
	tbl.innerHTML = "";
309
	const row = tbl.insertRow(-1);
310
	const cell = row.insertCell(-1);
311
	cell.textContent = "0";
312
313
	const rowsPerPage = Math.floor(getComputedStyle(document.getElementById("div_inbox")).height.replace("px", "") / getComputedStyle(document.querySelector("#tbl_inbox > tbody > tr:first-child")).height.replace("px", "")) - 1; // -1 allows space for 'load more'
314
	tbl.innerHTML = "";
315
	return rowsPerPage;
316
}
317
318
function addMessages() {
319
	const rowsPerPage = getRowsPerPage();
320
	let skipMsgs = rowsPerPage * tabs[TAB_INBOX].cur;
321
322
	const maxExt = ae.GetExtMsgCount();
323
	const maxInt = ae.GetIntMsgCount();
324
325
	tabs[TAB_INBOX].max = Math.floor((maxExt + maxInt) / rowsPerPage);
326
327
	let numExt = 0;
328
	let numInt = 0;
329
	let numAdd = 0;
330
331
	while (numAdd < rowsPerPage) {
332
		const tsInt = (numInt < maxInt) ? ae.GetIntMsgTime(numInt) : -1;
333
		const tsExt = (numExt < maxExt) ? ae.GetExtMsgTime(numExt) : -1;
334
		if (tsInt === -1 && tsExt === -1) break;
335
336
		if (tsInt !== -1 && (tsExt === -1 || tsInt > tsExt)) {
337
			if (skipMsgs > 0) skipMsgs--; else {addMsg(true, numInt); numAdd++;}
338
			numInt++;
339
		} else if (tsExt !== -1) {
340
			if (skipMsgs > 0) skipMsgs--; else {addMsg(false, numExt); numAdd++;}
341
			numExt++;
342
		}
343
	}
344
345
	if (ae.GetReadyMsgBytes() < ae.GetTotalMsgBytes()) {
346
		const inbox = document.getElementById("tbl_inbox");
347
		const row = inbox.insertRow(-1);
348
		const cell = row.insertCell(-1);
349
		cell.textContent = "Load more (" + (ae.GetTotalMsgBytes() - ae.GetReadyMsgBytes()) / 1024 + " KiB left)";
350
351
		row.onclick = function() {
352
			this.onclick = "";
353
354
			ae.Message_Browse(false, false, function(successBrowse) {
355
				document.getElementById("tbl_inbox").style.opacity = 1;
356
357
				if (successBrowse) {
358
					addMessages();
359
					addUploads();
360
					addSent();
361
					if (tabs[tab].cur < tabs[tab].max) document.getElementById("btn_rght").disabled = false;
362
				}
363
			});
364
		};
365
	}
366
}
367
368
function addUploads() {
369
	const tbl = document.getElementById("tbd_uploads");
370
	tbl.innerHTML = "";
371
372
	for (let i = 0; i < ae.GetUplMsgCount(); i++) {
373
		const row = tbl.insertRow(-1);
374
		let cell;
375
		cell = row.insertCell(-1); cell.textContent = new Date(ae.GetUplMsgTime(i) * 1000).toISOString().slice(0, 10);
376
377
		cell = row.insertCell(-1); cell.textContent = ae.GetUplMsgTitle(i);
378
		cell.onclick = function() {displayFile(this.parentElement.rowIndex - 1);};
379
380
		cell = row.insertCell(-1); cell.textContent = (ae.GetUplMsgBytes(i) / 1024).toFixed(1);
381
382
		cell = row.insertCell(-1);
383
		if (ae.GetUplMsgIdHex(i)) {
384
			cell.innerHTML = "<button data-msgid=\"" + ae.GetUplMsgIdHex(i) + "\" type=\"button\">X</button>";
385
386
			cell.children[0].onclick = function() {
387
				const tr = this.parentElement.parentElement;
388
				ae.Message_Delete(this.getAttribute("data-msgid"), function(success) {
389
					if (success) tr.remove();
390
				});
391
			};
392
		}
393
	}
394
}
395
396
function displayOutMsg(num) {
397
	clearDisplay();
398
	document.getElementById("midright").scroll(0, 0);
399
400
	document.getElementById("btn_reply").disabled = true;
401
	document.getElementById("btn_mdele").disabled = false;
402
	document.getElementById("btn_mdele").onclick = function() {
403
		this.blur();
404
		ae.Message_Delete(ae.GetOutMsgIdHex(num), function(success) {
405
			if (!success) console.log("Failed delete");
406
		});
407
	};
408
409
	document.getElementById("midright").children[0].hidden = false;
410
	document.getElementById("midright").children[2].hidden = false;
411
412
//	if (isInt) {
413
		document.getElementById("midright").children[1].textContent = ae.GetOutMsgSubj(num);
414
		document.getElementById("midright").children[2].textContent = ae.GetOutMsgBody(num);
415
//	} else {
416
//	}
417
418
	document.getElementById("readmsg_to").textContent = ae.GetOutMsgTo(num);
419
	document.getElementById("readmsg_envfrom").hidden = false;
420
	document.getElementById("readmsg_envfrom").textContent = ae.GetOutMsgFrom(num);
421
422
	const ts = ae.GetOutMsgTime(num);
423
	const tzOs = new Date().getTimezoneOffset();
424
	const tz = ((tzOs < 0) ? "+" : "-") + Math.floor(tzOs / -60).toString().padStart(2, "0") + (tzOs % 60 * -1).toString().padStart(2, "0");
425
	document.getElementById("readmsg_date").children[0].textContent = new Date((ts * 1000) + (tzOs * -60000)).toISOString().slice(0, 19).replace("T", " ") + " " + tz;
426
427
//	if (!isInt) {
428
		document.getElementById("readmsg_ip").hidden = false;
429
		document.getElementById("readmsg_country").hidden = false;
430
		document.getElementById("readmsg_tls").hidden = false;
431
		document.getElementById("readmsg_greet").hidden = false;
432
433
//		const cc = ae.GetExtMsgCountry(num);
434
435
		document.getElementById("readmsg_ip").children[0].textContent = ae.GetOutMsgIp(num);
436
//		document.getElementById("readmsg_country").textContent = getCountryFlag(cc) + " " + getCountryName(cc);
437
//		document.getElementById("readmsg_tls").children[0].textContent = ae.GetOutMsgTLS(num);
438
		document.getElementById("readmsg_greet").children[0].textContent = ae.GetOutMsgGreet(num);
439
//		document.getElementById("readmsg_envfrom").textContent = ae.GetExtMsgFrom(num);
440
//	} else {
441
//	}
442
}
443
444
function addSent() {
445
	const tbl = document.getElementById("tbl_drbox");
446
	tbl.innerHTML = "";
447
448
	for (let i = 0; i < ae.GetOutMsgCount(); i++) {
449
		const row = tbl.insertRow(-1);
450
		let cell;
451
452
		cell = row.insertCell(-1); cell.textContent = new Date(ae.GetOutMsgTime(i) * 1000).toISOString().slice(0, 10);
453
		cell = row.insertCell(-1); cell.textContent = ae.GetOutMsgSubj(i);
454
		row.onclick = function() {displayOutMsg(i);};
455
	}
456
}
457
458
function updateAddressCounts() {
459
	document.getElementById("limit_normal").textContent = (ae.GetAddressCountNormal() + "/" + ae.GetLimitNormalA(ae.GetUserLevel())).padStart(ae.GetLimitNormalA(ae.GetUserLevel()) > 9 ? 5 : 1);
460
	document.getElementById("limit_shield").textContent = (ae.GetAddressCountShield() + "/" + ae.GetLimitShieldA(ae.GetUserLevel())).padStart(ae.GetLimitShieldA(ae.GetUserLevel()) > 9 ? 5 : 1);
461
	document.getElementById("limit_total").textContent = ((ae.GetAddressCountNormal() + ae.GetAddressCountShield()) + "/" + ae.GetAddrPerUser()).padStart(5);
462
}
463
464
function adjustLevel(pubkey, level, c) {
465
	const fs = document.getElementById("fs_accs");
466
	fs.disabled = true;
467
468
	ae.Account_Update(pubkey, level, function(success) {
469
		fs.disabled = false;
470
471
		if (success) {
472
			c[4].textContent = level;
473
			c[5].children[0].disabled = (level === 3);
474
			c[6].children[0].disabled = (level === 0);
475
		}
476
	});
477
}
478
479
function addAccountToTable(i) {
480
	const tblAccs = document.getElementById("tbd_accs");
481
	const row = tblAccs.insertRow(-1);
482
	let cell;
483
	cell = row.insertCell(-1); cell.textContent = ae.Admin_GetUserPkHex(i);
484
	cell = row.insertCell(-1); cell.textContent = ae.Admin_GetUserSpace(i);
485
	cell = row.insertCell(-1); cell.textContent = ae.Admin_GetUserNAddr(i);
486
	cell = row.insertCell(-1); cell.textContent = ae.Admin_GetUserSAddr(i);
487
	cell = row.insertCell(-1); cell.textContent = ae.Admin_GetUserLevel(i);
488
489
	cell = row.insertCell(-1); cell.innerHTML = "<button type=\"button\" autocomplete=\"off\">+</button>";
490
	cell.children[0].onclick = function() {const c = this.parentElement.parentElement.cells; adjustLevel(c[0].textContent, parseInt(c[4].textContent) + 1, c);};
491
	cell.children[0].disabled = (ae.Admin_GetUserLevel(i) === 3);
492
493
	cell = row.insertCell(-1); cell.innerHTML = "<button type=\"button\" autocomplete=\"off\">&minus;</button>";
494
	cell.children[0].onclick = function() {const c = this.parentElement.parentElement.cells; adjustLevel(c[0].textContent, parseInt(c[4].textContent) - 1, c);};
495
	cell.children[0].disabled = (ae.Admin_GetUserLevel(i) === 0);
496
497
	cell = row.insertCell(-1); cell.innerHTML = "<button type=\"button\" autocomplete=\"off\">X</button>";
498
	cell.children[0].onclick = function() {
499
		const tr = this.parentElement.parentElement;
500
		ae.Account_Delete(tr.cells[0].textContent, function(success) {
501
			if (success) tr.remove();
502
		});
503
	};
504
}
505
506
function reloadAccount() {
507
	// Limits
508
	const tblLimits = document.getElementById("tbl_limits");
509
	if (ae.IsUserAdmin()) {
510
		for (let i = 0; i < 4; i++) {
511
			tblLimits.rows[i].cells[1].children[0].disabled = false;
512
			tblLimits.rows[i].cells[2].children[0].disabled = false;
513
			tblLimits.rows[i].cells[3].children[0].disabled = false;
514
515
			tblLimits.rows[i].cells[1].children[0].value = ae.GetLimitStorage(i) + 1;
516
			tblLimits.rows[i].cells[2].children[0].value = ae.GetLimitNormalA(i);
517
			tblLimits.rows[i].cells[3].children[0].value = ae.GetLimitShieldA(i);
518
		}
519
	} else {
520
		const lvl = ae.GetUserLevel();
521
		tblLimits.rows[lvl].cells[1].children[0].value = ae.GetLimitStorage(lvl) + 1;
522
		tblLimits.rows[lvl].cells[2].children[0].value = ae.GetLimitNormalA(lvl);
523
		tblLimits.rows[lvl].cells[3].children[0].value = ae.GetLimitShieldA(lvl);
524
	}
525
526
	// Accounts
527
	const tblAccs = document.getElementById("tbd_accs");
528
529
	// All: Our account
530
	const row = tblAccs.insertRow(-1);
531
	let cell;
532
	cell = row.insertCell(-1); cell.textContent = ae.GetUserPkHex();
533
	cell = row.insertCell(-1); cell.textContent = Math.round(ae.GetTotalMsgBytes() / 1024 / 1024);
534
	cell = row.insertCell(-1); cell.textContent = ae.GetAddressCountNormal();
535
	cell = row.insertCell(-1); cell.textContent = ae.GetAddressCountShield();
536
	cell = row.insertCell(-1); cell.textContent = ae.GetUserLevel();
537
	cell = row.insertCell(-1); cell.innerHTML = "<button type=\"button\" autocomplete=\"off\" disabled=\"disabled\">+</button>";
538
539
	cell = row.insertCell(-1); cell.innerHTML = "<button id=\"btn_downme\" type=\"button\" autocomplete=\"off\" disabled=\"disabled\">&minus;</button>";
540
	cell.children[0].onclick = function() {
541
		const newLevel = parseInt(row.cells[4].textContent) - 1;
542
		ae.Account_Update(ae.GetUserPkHex(), newLevel, function(success) {
543
			if (success) row.cells[4].textContent = newLevel;
544
		});
545
	};
546
547
	cell = row.insertCell(-1); cell.innerHTML = "<button id=\"btn_killme\" type=\"button\" autocomplete=\"off\" disabled=\"disabled\">X</button>";
548
	cell.children[0].onclick = function() {
549
		ae.Account_Delete(ae.GetUserPkHex(), function(success) {
550
			if (success) row.remove();
551
		});
552
	};
553
554
	document.getElementById("txt_reg").disabled = !ae.IsUserAdmin();
555
	document.getElementById("btn_reg").disabled = !ae.IsUserAdmin();
556
557
	// Contacts
558
	for (let i = 0; i < ae.GetContactCount(); i++) {
559
		addContact(
560
			ae.GetContactMail(i),
561
			ae.GetContactName(i),
562
			ae.GetContactNote(i)
563
		);
564
	}
565
566
	// Addresses
567
	for (let i = 0; i < ae.GetAddressCount(); i++) {
568
		addAddress(i);
569
	}
570
571
	updateAddressCounts();
572
	addMessages();
573
	addUploads();
574
	addSent();
575
}
576
577
function deleteAddress(addr) {
578
	let btns = document.getElementById("tbl_addrs").getElementsByTagName("button");
579
	for (let i = 0; i < btns.length; i++) btns[i].disabled = true;
580
581
	let addressToDelete = -1;
582
583
	for (let i = 0; i < ae.GetAddressCount(); i++) {
584
		if (addr === ae.GetAddress(i)) {
585
			addressToDelete = i;
586
			break;
587
		}
588
	}
589
590
	if (addressToDelete === -1) return;
591
592
	ae.Address_Delete(addressToDelete, function(success) {
593
		if (success) {
594
			document.getElementById("tbl_addrs").deleteRow(addressToDelete);
595
			document.getElementById("write_from").remove(addressToDelete);
596
			updateAddressCounts();
597
598
			if (ae.GetAddressCountNormal() < ae.GetLimitNormalA(ae.GetUserLevel())) document.getElementById("btn_address_create_normal").disabled = false;
599
			if (ae.GetAddressCountShield() < ae.GetLimitShieldA(ae.GetUserLevel())) document.getElementById("btn_address_create_shield").disabled = false;
600
601
			ae.Private_Update(function(success2) {
602
				if (!success2) console.log("Failed to update the Private field");
603
604
				btns = document.getElementById("tbl_addrs").getElementsByTagName("button");
605
				for (let i = 0; i < btns.length; i++) btns[i].disabled = false;
606
			});
607
		} else {
608
			console.log("Failed to delete address");
609
610
			btns = document.getElementById("tbl_addrs").getElementsByTagName("button");
611
			for (let i = 0; i < btns.length; i++) btns[i].disabled = false;
612
		}
613
	});
614
}
615
616 View Code Duplication
function shieldMix(addr) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
617
	let newAddr = "";
618
619
	for (let i = 0; i < 16; i++) {
620
		switch (addr.charAt(i)) {
621
			case '1':
622
				newAddr += "1iIlL".charAt(Math.floor(Math.random() * 5));
623
				break;
624
			case '0':
625
				newAddr += "0oO".charAt(Math.floor(Math.random() * 3));
626
				break;
627
			case 'w':
628
				newAddr += "VvWw".charAt(Math.floor(Math.random() * 4));
629
				break;
630
			default:
631
				newAddr += (Math.random() > 0.5) ? addr.charAt(i) : addr.charAt(i).toUpperCase();
632
		}
633
	}
634
635
	return newAddr;
636
}
637
638
function addAddress(num) {
639
	const addrTable = document.getElementById("tbl_addrs");
640
	const row = addrTable.insertRow(-1);
641
	const cellAddr = row.insertCell(-1);
642
	const cellChk1 = row.insertCell(-1);
643
	const cellChk2 = row.insertCell(-1);
644
	const cellChk3 = row.insertCell(-1);
645
	const cellBtnD = row.insertCell(-1);
646
647
	cellAddr.textContent = ae.GetAddress(num);
648
	cellAddr.onclick = function() {
649
		if (cellAddr.textContent.length === 16)
650
			navigator.clipboard.writeText(shieldMix(cellAddr.textContent) + "@" + ae.GetDomainEml());
1 ignored issue
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
651
		else
652
			navigator.clipboard.writeText(cellAddr.textContent + "@" + ae.GetDomainEml());
653
	};
654
655
	cellChk1.innerHTML = ae.GetAddressAccExt(num) ? "<input type=\"checkbox\" checked=\"checked\">" : "<input type=\"checkbox\">";
656
	cellChk2.innerHTML = ae.GetAddressAccInt(num) ? "<input type=\"checkbox\" checked=\"checked\">" : "<input type=\"checkbox\">";
657
	cellChk3.innerHTML = ae.GetAddressUse_Gk(num) ? "<input type=\"checkbox\" checked=\"checked\">" : "<input type=\"checkbox\">";
658
659
	cellBtnD.innerHTML = "<button type=\"button\">X</button>";
660
	cellBtnD.onclick = function() {deleteAddress(cellAddr.textContent);};
661
662
	const opt = document.createElement("option");
663
	opt.value = cellAddr.textContent;
664
	opt.textContent = cellAddr.textContent + "@" + ae.GetDomainEml();
665
	document.getElementById("write_from").appendChild(opt);
666
}
667
668
document.getElementById("btn_dele").onclick = function() {
669
	this.blur();
670
671
	if (tab === TAB_WRITE) {
672
		tabs[tab].cur = 0;
673
		updateTab();
674
675
		document.getElementById("write_recv").value = "";
676
		document.getElementById("write_subj").value = "";
677
		document.getElementById("write_body").value = "";
678
679
		document.getElementById("write_recv").focus();
680
	}
681
};
682
683
document.getElementById("btn_updt").onclick = function() {
684
	const btn = this;
685
	btn.disabled = true;
686
	btn.blur();
687
688
	if (tab === TAB_INBOX) {
689
		document.getElementById("tbl_inbox").style.opacity = 0.5;
690
691
		ae.Message_Browse(true, false, function(successBrowse) {
692
			document.getElementById("tbl_inbox").style.opacity = 1;
693
694
			if (successBrowse) {
695
				addMessages();
696
				addUploads();
697
				btn.disabled = false;
698
			} else {
699
				console.log("Failed to refresh");
700
				btn.disabled = false;
701
			}
702
		});
703
	}
704
};
705
706
function addContact(mail, name, note) {
707
	const tbl = document.getElementById("tbl_ctact");
708
	const row = tbl.insertRow(-1);
709
	const cellMail = row.insertCell(-1);
710
	const cellName = row.insertCell(-1);
711
	const cellNote = row.insertCell(-1);
712
	const cellBtnD = row.insertCell(-1);
713
714
	cellMail.textContent = mail;
715
	cellName.textContent = name;
716
	cellNote.textContent = note;
717
	cellBtnD.innerHTML = "<button type=\"button\">X</button>";
718
719
	cellMail.contentEditable = true;
720
	cellName.contentEditable = true;
721
	cellNote.contentEditable = true;
722
723
	cellBtnD.onclick = function() {row.remove();};
724
}
725
726
document.getElementById("btn_newcontact").onclick = function() {
727
	addContact("", "", "");
728
};
729
730
document.getElementById("btn_savecontacts").onclick = function() {
731
	while (ae.GetContactCount() > 0) {
732
		ae.DeleteContact(0);
733
	}
734
735
	for (const row of document.getElementById("tbl_ctact").rows) {
736
		ae.AddContact(row.cells[0].textContent, row.cells[1].textContent, row.cells[2].textContent);
737
	}
738
739
	const btn = this;
740
	btn.disabled = true;
741
742
	ae.Private_Update(function(success) {
743
		btn.disabled = false;
744
745
		if (!success) {
746
			console.log("Failed contacts update");
747
		}
748
	});
749
};
750
751
function writeVerify() {
752
	document.getElementById("div_write_1").hidden = true;
753
	document.getElementById("div_write_2").hidden = false;
754
755
	document.getElementById("write2_recv").textContent = document.getElementById("write_recv").value;
756
	document.getElementById("write2_subj").textContent = document.getElementById("write_subj").value;
757
	document.getElementById("write2_rply").textContent = document.getElementById("write_rply").textContent;
758
	document.getElementById("write2_body").textContent = document.getElementById("write_body").value;
759
760
	if (document.getElementById("write_recv").value.indexOf("@") >= 0)
761
		document.getElementById("write2_from").textContent = document.getElementById("write_from").value + "@" + ae.GetDomainEml();
762
	else
763
		document.getElementById("write2_from").textContent = document.getElementById("write_from").value;
764
765
//	document.getElementById("write2_pkey").textContent = sodium.to_hex(pk);
766
}
767
768
function updateTab() {
769
	switch (tab) {
770
		case TAB_INBOX:
771
			addMessages();
772
		break;
773
774
		case TAB_DRBOX:
775
			addSent();
776
		break;
777
778
		case TAB_WRITE:
779
			switch (tabs[tab].cur) {
780
				case 0: // Write
781
					document.getElementById("div_write_1").hidden = false;
782
					document.getElementById("div_write_2").hidden = true;
783
					document.getElementById("write_body").focus();
784
				break;
785
786
				case 1: // Verify
787
					if (document.getElementById("write_recv").value.indexOf("@") >= 0) {
788
						ae.Address_Lookup(document.getElementById("write_recv").value, function(pk) {
789
							if (!pk) {
790
								console.log("Failed lookup");
791
								return;
792
							}
793
794
							writeVerify();
795
						});
796
					} else writeVerify();
797
				break;
798
799
				case 2: // Send
800
					ae.Message_Create(
801
						document.getElementById("write_subj").value,
802
						document.getElementById("write_body").value,
803
						document.getElementById("write_from").value,
804
						document.getElementById("write_recv").value,
805
						document.getElementById("write_rply").textContent,
806
						(document.getElementById("write2_recv").textContent.indexOf("@") > 0) ? null : sodium.from_hex(document.getElementById("write2_pkey").textContent),
1 ignored issue
show
Bug introduced by
The variable sodium seems to be never declared. If this is a global, consider adding a /** global: sodium */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
807
						function(success) {
808
							if (success) {
809
								console.log("Sent ok");
810
							} else {
811
								console.log("Failed sending");
812
							}
813
						}
814
					);
815
				break;
816
			}
817
		break;
818
819
		case TAB_NOTES:
820
			for (let i = 0; i <= tabs[tab].max; i++) {
821
				document.getElementById("div_notes").children[i].hidden = (i !== tabs[tab].cur);
822
			}
823
		break;
824
825
		case TAB_TOOLS:
826
			for (let i = 0; i <= tabs[tab].max; i++) {
827
				document.getElementById("div_tools").children[i].hidden = (i !== tabs[tab].cur);
828
			}
829
		break;
830
	}
831
832
	document.getElementById("btn_left").disabled = (tabs[tab].cur === 0);
833
	document.getElementById("btn_rght").disabled = (tabs[tab].cur === tabs[tab].max);
834
}
835
836
document.getElementById("btn_left").onclick = function() {
837
	tabs[tab].cur--;
838
	if (tabs[tab].cur === 0) this.disabled = true;
839
	if (tabs[tab].cur < tabs[tab].max) document.getElementById("btn_rght").disabled = false;
840
	updateTab();
841
	this.blur();
842
};
843
844
document.getElementById("btn_rght").onclick = function() {
845
	tabs[tab].cur++;
846
	if (tabs[tab].cur === tabs[tab].max) this.disabled = true;
847
	document.getElementById("btn_left").disabled = false;
848
	updateTab();
849
	this.blur();
850
};
851
852
const buttons = document.querySelector("#main1 > .top").getElementsByTagName("button");
853
for (let i = 0; i < buttons.length; i++) {
854
	buttons[i].onclick = function() {
855
		tab = i;
856
857
		for (let j = 0; j < buttons.length; j++) {
858
			document.querySelector("#main1 > .mid").children[j].hidden = (tab !== j);
859
			buttons[j].disabled = (tab === j);
860
		}
861
862
		document.getElementById("btn_left").disabled = (tabs[tab].cur === 0);
0 ignored issues
show
Bug introduced by
The variable tab is changed as part of the for loop for example by i on line 855. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
863
		document.getElementById("btn_rght").disabled = (tabs[tab].cur === tabs[tab].max);
864
		document.getElementById("btn_dele").disabled = !tabs[tab].btnDele;
865
		document.getElementById("btn_updt").disabled = !tabs[tab].btnUpdt;
866
	};
867
}
868
869
function addressCreate(addr) {
870
	const btnN = document.getElementById("btn_address_create_normal");
871
	const btnS = document.getElementById("btn_address_create_shield");
872
	btnN.disabled = true;
873
	btnS.disabled = true;
874
875
	ae.Address_Create(addr, function(success1) {
876
		if (success1) {
877
			ae.Private_Update(function(success2) {
878
				addAddress(ae.GetAddressCount() - 1);
879
				if (addr !== "SHIELD") document.getElementById("txt_address_create_normal").value = "";
880
				updateAddressCounts();
881
882
				if (!success2) console.log("Failed to update the Private field");
883
884
				if (ae.GetAddressCountNormal() < ae.GetLimitNormalA(ae.GetUserLevel())) btnN.disabled = false;
885
				if (ae.GetAddressCountShield() < ae.GetLimitShieldA(ae.GetUserLevel())) btnS.disabled = false;
886
			});
887
		} else {
888
			console.log("Failed to add address");
889
890
			if (ae.GetAddressCountNormal() < ae.GetLimitNormalA(ae.GetUserLevel())) btnN.disabled = false;
891
			if (ae.GetAddressCountShield() < ae.GetLimitShieldA(ae.GetUserLevel())) btnS.disabled = false;
892
		}
893
	});
894
}
895
896
document.getElementById("btn_address_create_normal").onclick = function() {
897
	if (ae.GetAddressCountNormal() >= ae.GetLimitNormalA(ae.GetUserLevel())) return;
898
899
	const txtNewAddr = document.getElementById("txt_address_create_normal");
900
	if (!txtNewAddr.reportValidity()) return;
901
902
	addressCreate(txtNewAddr.value);
903
};
904
905
document.getElementById("btn_address_create_shield").onclick = function() {
906
	if (ae.GetAddressCountShield() >= ae.GetLimitShieldA(ae.GetUserLevel())) return;
907
908
	addressCreate("SHIELD");
909
};
910
911
document.getElementById("btn_reg").onclick = function() {
912
	const btn = document.getElementById("btn_reg");
913
	const txt = document.getElementById("txt_reg");
914
	if (!txt.reportValidity()) return;
915
	btn.disabled = true;
916
917
	ae.Account_Create(txt.value, function(success) {
918
		if (success) {
919
			addAccountToTable(ae.Admin_GetUserCount() - 1);
920
			txt.value = "";
921
		}
922
923
		btn.disabled = false;
924
	});
925
};
926
927
document.getElementById("chk_downme").onclick = function() {document.getElementById("btn_downme").disabled = !this.checked;};
928
document.getElementById("chk_killme").onclick = function() {document.getElementById("btn_killme").disabled = !this.checked;};
929
930
document.getElementById("btn_notepad_saveupl").onclick = function() {
931
	const np = document.getElementById("txt_notepad");
932
	np.disabled = true;
933
934
	let fname = prompt("Save as...", "Untitled");
0 ignored issues
show
Debugging Code Best Practice introduced by
The prompt UI element is often considered obtrusive and is generally only used as a temporary measure. Consider replacing it with another UI element.
Loading history...
935
	if (!fname.endsWith(".txt")) fname += ".txt";
936
937
	ae.Message_Upload(fname, np.value, function(success) {
938
		if (success) {
939
			np.value = "";
940
			addUploads();
941
			document.getElementById("tbd_accs").children[0].children[1].textContent = Math.round(ae.GetTotalMsgBytes() / 1024 / 1024);
942
		}
943
944
		console.log("Failed to add text");
945
		np.disabled = false;
946
	});
947
};
948
949
document.getElementById("btn_upload").onclick = function() {
950
	const btn = this;
951
	const fileSelector = document.createElement("input");
952
	fileSelector.type = "file";
953
	fileSelector.click();
954
955
	fileSelector.onchange = function() {
956
		btn.disabled = true;
957
958
		const reader = new FileReader();
1 ignored issue
show
Bug introduced by
The variable FileReader seems to be never declared. If this is a global, consider adding a /** global: FileReader */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
959
		reader.onload = function() {
960
			ae.Message_Upload(fileSelector.files[0].name, new Uint8Array(reader.result), function(success) {
961
				if (success) {
962
					addUploads();
963
					document.getElementById("tbd_accs").children[0].children[1].textContent = Math.round(ae.GetTotalMsgBytes() / 1024 / 1024);
964
				} else {
965
					console.log("Failed upload");
966
				}
967
968
				btn.disabled = false;
969
			});
970
		};
971
972
		reader.readAsArrayBuffer(fileSelector.files[0]);
973
	};
974
};
975
976
document.getElementById("btn_pg").onclick = function() {
977
	localStorage.greeting = document.getElementById("txt_pg").value;
1 ignored issue
show
Bug introduced by
The variable localStorage seems to be never declared. If this is a global, consider adding a /** global: localStorage */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
978
};
979
980
document.getElementById("txt_skey").onkeyup = function(event) {
981
	if (event.key === "Enter") {
982
		event.preventDefault();
983
		document.getElementById("btn_enter").click();
984
	}
985
};
986
987
document.getElementById("btn_enter").onclick = function() {
988
	const txtSkey = document.getElementById("txt_skey");
989
	if (!txtSkey.reportValidity()) return;
990
991
	const btn = this;
992
	btn.disabled = true;
993
	document.getElementById("txt_skey").style.background = "#233";
994
995
	ae.SetKeys(txtSkey.value, function(successSetKeys) {
996
		if (successSetKeys) {
997
			ae.Message_Browse(false, true, function(successBrowse) {
998
				if (successBrowse) {
999
					txtSkey.value = "";
1000
					document.getElementById("div_begin").hidden = true;
1001
					document.getElementById("div_main").style.display = "grid";
1002
					reloadAccount();
1003
1004
					if (ae.IsUserAdmin()) {
1005
						ae.Account_Browse(function(successAcc) {
1006
							if (successAcc) {for (let i = 0; i < ae.Admin_GetUserCount(); i++) {addAccountToTable(i);}}
1007
							else console.log("Failed to Account_Browse");
1008
						});
1009
					}
1010
				} else {
1011
					console.log("Failed to enter");
1012
					btn.disabled = false;
1013
					document.getElementById("txt_skey").style.background = "#466";
1014
					txtSkey.focus();
1015
				}
1016
			});
1017
		} else {
1018
			console.log("Invalid format for key");
1019
			btn.disabled = false;
1020
			document.getElementById("txt_skey").style.background = "#466";
1021
			txtSkey.focus();
1022
		}
1023
	});
1024
};
1025
1026
});
1027